#include "data.h"
#include <stdlib.h>
#include <time.h>

int score;
int grade;
//定义2个变量(食物 蛇)
Food food;
Snake snake;
//定义上一蛇尾坐标
int preX;
int preY;

//初始化一条蛇
//创建3个新结点 12,12 13,12 14,12
//分别给结点元素赋值
//连接三个结点
//设置蛇snake变量元素值
void dataInitSnake()
{
    SnakeNode *n1=(SnakeNode *)malloc(sizeof(SnakeNode));
    SnakeNode *n2=(SnakeNode *)malloc(sizeof(SnakeNode));
    SnakeNode *n3=(SnakeNode *)malloc(sizeof(SnakeNode));
    n1->x=14;
    n1->y=12;
    n2->x=13;
    n2->y=12;
    n3->x=12;
    n3->y=12;
    n1->next=n2;
    n2->next=n3;
    n3->next=NULL;
    snake.head=n1;
    snake.len=3;
    snake.dir=RIGHT;
}

// 食物位置校验 不能和蛇重合 返回1表示覆盖，返回0表未重合
int isCoverSnake(int x,int y)
{
    //遍历 蛇所有结点，逐个位置比较
    SnakeNode* node = snake.head;
    while(node)
    {
        if (node->x==x&&node->y==y)
            return 1;
        node=node->next;
    }
    return 0;
}

// 生成或更新食物坐标
void dataUpdateFood()
{
    //获取x y随机数，取值范围[0,23]
    int x,y;
    // 食物位置校验：不能和 蛇结点 重合
    int r;
    while(1)
    {
        x = rand() % 24;
        y = rand() % 24;
        r = isCoverSnake(x,y);
        if(r == 0)
            break;
    }
    food.x = x;
    food.y = y;
}

void dataInitData()
{
    //设置随机数种子
    srand((unsigned)time(NULL));
    score = 0;
    grade = 0;
    preX=-1;
    preY=-1;
    dataInitSnake();
    dataUpdateFood();
}

    //按照方向移动蛇
void dataSnakeMove(DIR dir)
{
    //定义新蛇头位置坐标
    int x = snake.head->x;
    int y = snake.head->y;
    //根据方向，获取新蛇头坐标
    if(dir==LEFT)
        x--;
    else if(dir==RIGHT)
        x++;
    else if (dir==UP)
        y--;
    else if (dir==DOWN)
        y++;
    //获取倒数第二个结点 倒数第一个结点
    SnakeNode *node=snake.head;
    while(node->next->next!=NULL)
    {
        node=node->next;
    }
    SnakeNode *tail=node->next;
    //记录原蛇尾坐标
    preX=tail->x;
    preY=tail->y;
    //将倒数第二个结点的next值设为NULL(改为蛇尾结点)
    node->next=NULL;
    //修改原蛇尾结点的坐标值为 新蛇头坐标值
    tail->x=x;
    tail->y=y;
    //将原蛇尾 头插法 插入链表
    tail->next=snake.head;
    //修改snake.head的值为 原蛇尾结点
    snake.head=tail;
}

//如果能咬到自己，则返回 1，否则返回0
int isBiteSelf(int x,int y)
{
    int r = isCoverSnake(x,y);
    return r;
}

//蛇移动，并返回移动后效果【撞墙|咬到自己，仅仅移动，吃到食物加分，吃到食物加分升级】
ReType dataMoveSnake2(DIR dir)
{
    //1.判断方向是否 相反
    // 如果两个方向不同，且运算结果为非0，则相反方向
    if((dir != snake.dir) && ((dir & snake.dir) != 0))
        return DirError;

    // 获取新蛇头坐标
    int x = snake.head->x;
    int y = snake.head->y;

    //根据方向，获取新蛇头坐标
    if(dir == UP){
        y--;
    }else if(dir == DOWN){
        y++;
    }else if(dir == LEFT){
        x--;
    }else if(dir == RIGHT){
        x++;
    }

    //2.判断是否撞墙
    if(x < 0 || x > 23 || y < 0 || y > 23)
        return Hit;

    //3.判断是否咬到自己
    if(isBiteSelf(x,y))
        return Hit;

    //dataSnakeMove(dir);
    //4.判断是否吃到食物
    if(x == food.x && y == food.y) {
        //a.创建新结点
        SnakeNode *node = (SnakeNode *)malloc(sizeof(SnakeNode));
        node->x = x;
        node->y = y;
        node->next = snake.head;

        //b.将新结点设置成头结点
        snake.head = node;
        snake.len++;
        snake.dir = dir;

        //c.分值增加
        score++;

        //食物更新
        dataUpdateFood();

        //d.等级增加
        if((score % 2 == 0)&&grade<8){
            grade+=2;
            return Grade;
        }
        return Score;
    }else {
    //5.仅仅移动即可
        //获取倒数第二个结点 倒数第一个结点(尾结点)
        SnakeNode *node = snake.head;
        while(node->next->next != NULL) {
            node = node->next;
        }
        //获取尾结点
        SnakeNode *tail = node->next;
        //记录上一尾结点的坐标值
        preX = tail->x;
        preY = tail->y;

        //将倒数第二个结点的next值设为NULL(改为蛇尾结点)
        node->next = NULL;

        //修改原蛇尾结点的坐标值为 新蛇头坐标值
        tail->x = x;
        tail->y = y;

        //将原蛇尾 头插法 插入链表
        tail->next = snake.head;

        //修改snake.head的值为 原蛇尾结点
        snake.head = tail;
        snake.dir = dir;

        return Move;
    }
}

